home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 08 - 1992 / 08.04 Aug 92 / Hello TCL World / TextPane.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-20  |  6.6 KB  |  287 lines  |  [TEXT/KAHL]

  1. /*                            TextPane.c                    */
  2. /*
  3.  * TextPane
  4.  *    Superclass: CPane.
  5.  * Copyright © 1991 Martin Minow. All Rights Reserved.
  6.  * All use and non-commercial distribution permitted.
  7.  * Set tabs every 4 bytes.
  8.  *
  9.  * This is a very simple text-only, output-only, display
  10.  * pane. It intentionally does not support cut/paste,
  11.  * scrolling, filing and printing.
  12.  */
  13.  
  14. #ifdef DOCUMENTATION
  15.  
  16. title        TextPane
  17. superclass    CPane
  18. subclasses    none
  19.  
  20. usage
  21.  
  22.     #include    "TextPane.h"
  23.     
  24.     void                    ITextPane(
  25.         CView            *anEnclosure,
  26.         CBureaucrat        *aSupervisor,
  27.         short            aWidth,
  28.         short            aHeight,
  29.         short            hEncl,
  30.         short            vEncl,
  31.         SizingOption    hSizing,
  32.         SizingOption    vSizing,
  33.         Str255            fontName,
  34.         short            fontHeight
  35.     );
  36.         Initialization: the parameters are as described in
  37.         the CPane documentation. fontName and fontHeight
  38.         define the font to be used to display the data.
  39.         This cannot be changed after initialization.
  40.                 
  41.     void                    Dispose(void);
  42.         Dispose of the TextPane and its contents.
  43.         
  44.     void                    SetText(
  45.         StringPtr        someText
  46.     );
  47.         Put a line of text on the screen.
  48.         It rolls text up the display.
  49.     
  50. author
  51.     Martin Minow
  52.  
  53. copyright
  54.     Copyright © 1991 Martin Minow. All Rights Reserved.
  55.     Non-commercial use and distribution permitted.
  56.     
  57. #endif
  58.  
  59. #include <CTextEnvirons.h>
  60. #include <TBUtilities.h>
  61. #include "TextPane.h"
  62.  
  63. #define itsTextInfo        ((CTextEnvirons *) itsEnvironment)
  64.  
  65.  
  66. /*
  67.  * The TextPane acts like a "glass teletype" -- messages
  68.  * appear at the bottom and are scrolled off the top
  69.  * (never to appear again). Since the TextPane is private
  70.  * and we know it will fill the window, the normal CPane
  71.  * parameters can be constructed here rather than being
  72.  * passed.  If this were a general-purpose pane, the full
  73.  * CPane parameters should be passed.
  74.  */
  75. PRIVATE void
  76. TextPane::ITextPane(
  77.         CView            *anEnclosure,
  78.         CBureaucrat        *aSupervisor,
  79.         short            aWidth,
  80.         short            aHeight,
  81.         short            aHEncl,
  82.         short            aVEncl,
  83.         SizingOption    aHSizing,
  84.         SizingOption    aVSizing,
  85.         Str255            fontName,
  86.         short            fontHeight
  87.     )
  88. {
  89.         register int            i;
  90.         TextInfoRec                aTextInfo;
  91.         register StringHandle    *theStrings;
  92.         FontInfo                info;
  93.         short                    fontNumber;
  94.         Rect                    textBox;
  95.         
  96.         CPane::IPane(
  97.             anEnclosure,
  98.             aSupervisor,
  99.             aWidth, aHeight,
  100.             aHEncl, aVEncl,
  101.             aHSizing, aVSizing
  102.         );
  103.         itsEnvironment = new(CTextEnvirons);
  104.         itsTextInfo->ITextEnvirons();
  105.         GetFontNumber(fontName, &fontNumber);
  106.         /*
  107.          * Make sure there's a drawing environment.
  108.          */
  109.         Prepare();
  110.         TextFont(fontNumber);
  111.         TextSize(fontHeight);
  112.         GetFontInfo(&info);
  113.         itsLineHeight = info.ascent
  114.                     + info.descent
  115.                     + info.leading;
  116.         /*
  117.          * Initialize the font stuff from the current port.
  118.          */
  119.         aTextInfo.fontNumber = thePort->txFont;
  120.         aTextInfo.theStyle = thePort->txFace;
  121.         aTextInfo.theSize = thePort->txSize;
  122.         aTextInfo.theMode = thePort->txMode;
  123.         itsTextInfo->SetTextInfo(&aTextInfo);
  124.         /*
  125.          * hOffset and vOffset define the initial position
  126.          * of the pen when drawing text.
  127.          */
  128.         hOffset = info.widMax / 2;
  129.         vOffset = info.ascent;
  130.         /*
  131.          * Determine the number of lines we will show.
  132.          */
  133.         GetAperture(&textBox);
  134.         itsNLines = (textBox.bottom - textBox.top);
  135.         itsNLines /= itsLineHeight;
  136.         /*
  137.          * Create a vector of strings. Note that this
  138.          * limits the class -- the application cannot
  139.          * change the font or window size after the window
  140.          * has been created.  A "real" application would
  141.          * display data in a CPanorama and store the strings
  142.          * in a CList subclass.
  143.          */
  144.         vectorHandle = (StringHandle **)
  145.             NewHandle(itsNLines * sizeof (StringHandle));
  146.         /*
  147.          * Lock the vectorHandle while we initialize
  148.          * the string vector.  This prevents any C compiler
  149.          * optimizations in the "theStrings[i] = ..."
  150.          * statement from causing "memory moved" problems.
  151.          */
  152.         MoveHHi(vectorHandle);
  153.         HLock(vectorHandle);
  154.         theStrings = *vectorHandle;
  155.         for (i = 0; i < itsNLines; i++)
  156.             theStrings[i] = NewString((StringPtr) "\p");
  157.         HUnlock(vectorHandle);
  158. }
  159.  
  160. /*
  161.  * Dispose of the TextPane by deleting the strings and
  162.  * the string vector. This is called by TCL when the
  163.  * enclosing window is disposed. (Note also that TCL
  164.  * will dispose of the environment object, too.)
  165.  */
  166. void
  167. TextPane::Dispose()
  168. {
  169.         register int            i;
  170.         register StringHandle    *theStrings;
  171.         
  172.         HLock(vectorHandle);
  173.         theStrings = *vectorHandle;
  174.         for (i = 0; i < itsNLines; i++)
  175.             DisposHandle(theStrings[i]);
  176.         DisposHandle(vectorHandle);
  177.         inherited::Dispose();
  178. }
  179.  
  180. /*
  181.  * The SetText method adds text to the TextPane.
  182.  */
  183. void
  184. TextPane::SetText(
  185.         StringPtr        someText
  186.     )
  187. {
  188.         register StringHandle    *theStrings;
  189.         StringHandle            tempHandle;
  190.         register int            i;
  191.         
  192.         theStrings = (StringHandle *) *vectorHandle;
  193.         /*
  194.          * Save the top string's handle for recycling,
  195.          * move the others "up" in the display,
  196.          * insert the old top string at the bottom,
  197.          * and set its contents to the supplied value.
  198.          * Finally, update the display.
  199.          * Note that we must not depend on the value
  200.          * of theStrings after calling SetString or
  201.          * ScrollPane as either may move memory.
  202.          *
  203.     ***     * The following sequence may not move memory.
  204.          */
  205.         tempHandle = theStrings[0];
  206.         for (i = 1; i < itsNLines; i++)
  207.             theStrings[i - 1] = theStrings[i];
  208.         theStrings[itsNLines - 1] = tempHandle;
  209.         /*
  210.     ***     * The above sequence may not move memory.
  211.          */
  212.         SetString(tempHandle, someText);
  213.         ScrollPane();
  214. }
  215.  
  216. /*
  217.  * This is the only function that accesses the text.
  218.  */
  219. StringHandle
  220. TextPane::GetText(
  221.         short            whichItem
  222.     )
  223. {
  224.         return ((*vectorHandle)[whichItem]);
  225. }
  226.  
  227.  
  228. /*
  229.  * Draw is called by the TCL when part of the TextPane
  230.  * has been uncovered.  Note that the actual drawing
  231.  * is done by a DrawItem method -- this lets us have
  232.  * one common routine for both Draw and ScrollPane.
  233.  * This is overkill for this demo application, but useful
  234.  * when the thing being drawn is complex.
  235.  */
  236. void
  237. TextPane::Draw(
  238.         Rect            *area
  239.     )
  240. {
  241.         register int            i;
  242.  
  243.         for (i = 0; i < itsNLines; i++)
  244.             DrawItem(i);
  245. }
  246.  
  247. /*
  248.  * This method scrolls the text pane up one line and draws
  249.  * the last line (which has just been inserted).
  250.  */
  251. PRIVATE void
  252. TextPane::ScrollPane()
  253. {
  254.         Rect                    theView;
  255.         RgnHandle                tempRgn;
  256.         
  257.         Prepare();
  258.         tempRgn = NewRgn();
  259.         GetAperture(&theView);
  260.         ScrollRect(&theView, 0, -itsLineHeight, tempRgn);
  261.         DrawItem(itsNLines - 1);
  262.         ValidRgn(tempRgn);
  263.         DisposeRgn(tempRgn);
  264. }
  265.  
  266. /*
  267.  * This is the only function that draws the data.
  268.  */
  269. PRIVATE void
  270. TextPane::DrawItem(
  271.         short            whichItem
  272.     )
  273. {
  274.         register StringHandle    theString;
  275.         SignedByte                saveHState;
  276.                 
  277.         theString = GetText(whichItem);
  278.         saveHState = HGetState(theString);
  279.         HLock(theString);
  280.         MoveTo(
  281.             hOffset,
  282.             vOffset + (whichItem * itsLineHeight)
  283.         );
  284.         DrawString(*theString);
  285.         HSetState(theString, saveHState);
  286. }
  287.